package com.study.util;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.security.AnyTypePermission;

/**
 * @description XStream工具类
 * @author KWCHEN
 * @version v1.0
 * @date 2019年7月2日
 */
public class XStreamUtil {

	private static String XML_TAG = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";

	/**
	 * 私有化构造
	 */
	private XStreamUtil() {
		super();
	}

	@SuppressWarnings("deprecation")
	public static XStream getInstance() {
		XStream xStream = new XStream(new DomDriver("UTF-8")) {
			/**
			 * 忽略xml中多余字段
			 */
			@Override
			protected MapperWrapper wrapMapper(MapperWrapper next) {
				return new MapperWrapper(next) {
					@SuppressWarnings("rawtypes")
					@Override
					public boolean shouldSerializeMember(Class definedIn, String fieldName) {
						if (definedIn == Object.class) {
							return false;
						}
						return super.shouldSerializeMember(definedIn, fieldName);
					}

				};
			}

		};
		// 设置默认的安全校验
		XStream.setupDefaultSecurity(xStream);
		// 使用本地的类加载器
		xStream.setClassLoader(XStreamUtil.class.getClassLoader());
		// 允许所有的类进行转换
		xStream.addPermission(AnyTypePermission.ANY);

		return xStream;
	}

	/**
	 * 将xml字符串转换为java对象
	 * 
	 * @param xml
	 * @param clazz
	 * @return
	 */
	public static <T> T xmlToBean(String xml, Class<T> clazz) {
		XStream xStream = getInstance();
		// 处理注解
		xStream.processAnnotations(clazz);
		Object object = xStream.fromXML(xml);
		T cast = clazz.cast(object);
		return cast;
	}

	/**
	 * 将java对象转换为xml字符串
	 * 
	 * @param object
	 * @return
	 */
	public static String beanToXml(Object object) {
		XStream xStream = getInstance();
		xStream.processAnnotations(object.getClass());
		// 剔除所有tab、制表符、换行符
		String xml = xStream.toXML(object).replaceAll("\\s+", "	");
		return xml;
	}

	/**
	 * 将java对象转化为xml字符串（包含xml头部信息）
	 * 
	 * @param object
	 * @return
	 */
	public static String beanToXmlWithTag(Object object) {
		String xml = XML_TAG + beanToXml(object);
		return xml;
	}
}
